;(function($){
var common=common||{version:'1.0.0'};
//气泡
common.pop=function(options){
			var settings={
				id:'J_popover_chk',
				title:'',
				content:'',
				top:0,
				left:0,				
				pannel:'',//容器
				type:'form-chk right',
				autohide:false 
			};
			 
			settings=$.extend({},settings,options);
			//应用bs工具提示
			var _p_html='<div class="popover '+(settings.type||'form-chk right')  +'" style="display:none"><div class="arrow"></div><div class="popover-content"></div></div>';			
			//标示唯一
		    var obj=$(_p_html).attr('id',settings.id||'J_popover_chk');
			if(!$('#'+(settings.id||'J_popover_chk'))[0] ){
				if(settings.pannel!=''&&settings.pannel!=null){
					obj.appendTo(settings.pannel);
				}else{
					obj.appendTo('body');	
				}					
			}else{
				obj=$('#'+(settings.id||'J_popover_chk'));
			}			
			obj.css({position:'absolute',top:settings.top,left:settings.left});	
			//加入内容
			if(settings.content==''||settings.content==null||$(settings.content).text()==''){
				obj.remove();	
			}else{
				obj.find('.popover-content').html(settings.content);
				obj.show();	
			}
			return obj;
};
//验证插件
var Validator=function( form ,options){
			if(!form[0]){
				//未指定容器，不处理验证
				return;
			}
			var settings={
				submit:function(fm){				
					//提交验证	
				},
				//验证规则
				valids:{}
			};			
			//合并用户配置
			settings=$.extend({},settings,options);
			
			//支持验证的控件 
			//目前支持 有name的 input textarea 控件
			var controls=':text[name],:password[name],textarea[name]';
			 
			//扩展方法
			$.extend(form,{
				//获取指定控件的验证规则
				getruls:function(input){
					var name=input.prop('name'),
						valid=input.attr('data-valid')||{}, 	//控件上的验证
						optvalid=settings.valids[name]||{};   	//自定义的验证
					var rule=$.extend({},valid,optvalid);
					return rule;
				},
				//解决重名name引起的问题
				geterrorname:function(input){
					//控件名
					var input_name=input.prop('name');
					//同名控件排序
					var index=  input.index('[name="'+input_name+'"]');
					return input_name.replace(/[\[\]]+/,'')+index.toString()+'error';
				},
				//创建提示框
				//input 验证的输入框
				//opt 对应input的验证规则
				//flag 创建后是否直接验证
				createvalid:function(input,opt,flag){
					var id= this.geterrorname(input) ;
					var rules=opt.rules||[];
					//消息提示显示位置
					var _left=0,_top=0,_p_h=0,_p_w=0,_type='form-chk right J_form_tips';
					// li 行高   ,ul 上下内距
					var _li_h=20,_ul_tp_p=5;
					//提示消息
					var msg=$('<ul></ul>');
					var msg_count=0;
					if($('#'+id)[0]){
						return;
					}
					//必填项,无分组
					if(opt.require||false){					
						$('<li><i class="icon-checked"></i>必填项</li>').appendTo( msg );
						msg_count++;
					}
					//规则提示, 引入分组
					for(var i=0;i<rules.length;i++){
						
						$('<li '+  (rules[i].hasOwnProperty('group')?('chk-group="'+rules[i].group+'"'):'')  +'><i class="icon-checked"></i>'+ rules[i].msg +'</li>').appendTo( msg );
						msg_count++;
					}
					//如果是组合框，则取组合框外部位置
					var div_input= input.parents('div.input-append,div.input-prepend,div.input-comb');
					if(div_input[0]){
						_p_h= div_input.outerHeight(true);
						_p_w= div_input.outerWidth(true);	
						_top=  div_input.offset().top-   (msg_count*_li_h /2  +  _ul_tp_p*2) + _p_h/2;					 
						_left= div_input.offset().left+div_input.outerWidth(true);
						
					}else{
						_p_h= input.outerHeight(true);
						_p_w= input.outerWidth(true);						
						_top= input.offset().top-  (msg_count*_li_h/2  +  _ul_tp_p*2 )+ _p_h/2;
						_left=input.offset().left+ _p_w;
					}
					
					if(_top<0){						
					   _top=  div_input[0]? (div_input.offset().top+ _p_h) : (input.offset().top+ _p_h);
					   _left= div_input[0]? div_input.offset().left: input.offset().left;
					   _type='form-chk bottom J_form_tips';	
					}else{
						//
					}
					
					//显示错误信息
					var fchk= common.pop({
						id:id,
						content:msg.prop('outerHTML'),
						top:_top,
						left:_left,
						type:_type
					});	
					fchk.attr('data-type','validator');
					
					//兼容一下折叠面板
					if(input.parents('.accordion-group')[0]){
						if(!input.parents('.accordion-group').find('.accordion-body').hasClass('in')){
							input.parents('.accordion-group').find('.accordion-toggle').trigger('click');	
						}
					}					
					
					if(flag){
						this.valid( input,opt );
					}
				},
				//异步验证
				//url 验证地址
				//id 错误容器id
				//index 错误项
				remote:function(url,params,id,index){
					var obj=this;
					$.getJSON(url,params ,function(res){								
						if(res.errcode==0){
							obj.showerror(id,index, true,res.errmsg );
						}else{
							obj.showerror(id,index, false,res.errmsg );
						}
					});
				},
				//字符数
				bytelength:function(str){
					return str.replace(/[^\x00-\xff]/g,"00").length;
				},
				//极值验证，最长
				extrememax:function(input,rules){					
					var val=input.val();
					var flag=true;
					$(rules).each(function(){
						var rule=$(this)[0];						
						if(rule.hasOwnProperty('max')&& !isNaN( val )){							
							//暂时只做最长验证
							//flag = val*1<=rule.max;
						}else if(rule.hasOwnProperty('maxlen')){
							flag = val.length<= rule.maxlen;
							if(!flag){
								val= val.substr(0,rule.maxlen);
								input.val(val);
							}
						}
						return flag;
					});
					return flag;
				},
				//对指定控件进行验证
				valid:function(input,opt){
					var obj=this;
					var rules=opt.rules||[];
					var name=input.prop('name');
					var value= $.trim(input.val())||'';
					if(input.prop('tagName').toLowerCase()=='textarea'){
						//value=input.text()||'';
					}
					
					var errorname=obj.geterrorname(input) ;
					//是否必填
					var ismust=opt.require||false;
					//是否验证通过,只要有一个不通过，则为false
					var ischk=true;					
					var isitemchk=true;
					var remote_index=-1;
					//分组的
					var group_chk={};
					
					//必填验证
					if(ismust){
						ischk=value!='';
						obj.showerror(errorname,0,value!='');
					}
					
					//执行值验证
					var check_rule=function(isnotnull,rule,val){
						//非空, 或value不为空时
						if(isnotnull||val!=''){							
							//关联主输入框验证
							if(rule.hasOwnProperty('master')){
								
								if(val!=  obj.find('[name="'+ rule.master +'"]') .val()   ){
									return false;
								}								
							}
							
							//min  max 验证 	值大小验证
							if(rule.hasOwnProperty('min')||rule.hasOwnProperty('max')){
								 if(isNaN(val)){
									return false;
								 }
								 
								 if( rule.hasOwnProperty('min')&&val<rule.min){
									 return false;
								 }
								 if( rule.hasOwnProperty('max')&&val>rule.max){
									 return false;
								 }
							}
							
							//minlen   maxlen 验证
							if(rule.hasOwnProperty('minlen')||rule.hasOwnProperty('maxlen')){								 
								 if( rule.hasOwnProperty('minlen')&& obj.bytelength(val)<rule.minlen){
									 return false;
								 }
								 if( rule.hasOwnProperty('maxlen')&&obj.bytelength(val)>rule.maxlen){
									 return false;
								 }
							}
							//正则验证
							if(rule.hasOwnProperty('regex')){
								var reg=new RegExp(rule.regex);
								return reg.test(val);	
							}
						}
						return true;
					};
					
					//验证结果
					var chk_result={};
					
					
					
					//其它验证
					for(var i=0;i<rules.length;i++){
						var rule=rules[i]||{};
						if(!rule.hasOwnProperty('regex')&&!rule.hasOwnProperty('remote')
						   &&!rule.hasOwnProperty('min')&&!rule.hasOwnProperty('max')
						   &&!rule.hasOwnProperty('minlen')&&!rule.hasOwnProperty('maxlen')
						   &&!rule.hasOwnProperty('master')
							){
							//不在验证范围
							continue;	
						}
						//异步验证
						if(rule.hasOwnProperty('remote')){
							remote_index=i;
							continue;
						}
						//无组验证
						if(!rule.hasOwnProperty('group')){							
							isitemchk= check_rule(ismust,rule,value );
							//输出错误
							obj.showerror(errorname,(ismust?(i+1):i),isitemchk);
						}else{//有组验证
							//组内排在前面的已验证通过
							if(group_chk.hasOwnProperty( rule.group )){
								if(!group_chk[ rule.group]){
									//
									group_chk[ rule.group]=	 check_rule(ismust,rule,value );	
								}
							}else{
								//添加分组验证
								group_chk[ rule.group]=	 check_rule(ismust,rule,value );
							}							
							obj.showerror(errorname,(ismust?(i+1):i),group_chk[ rule.group]);
						} 
						//
						ischk= ischk?isitemchk:ischk;
					}
					//合并有分组的
					for(var g in group_chk ){
						if(!group_chk[g]){
						  ischk=false;
						  break;
						}
					}
					
					//remote 验证
					if(ischk&&value!=''&&remote_index>=0){
						//必须是所有验证都通过后才去验证
						var params={};
						var rule= rules[remote_index];
						params[name]=value;
						obj.remote(rule.remote,params,errorname, (ismust?(remote_index+1):remote_index) );
					}
					return ischk;
				},
				//批量执行验证
				validates:function(){
					var obj=this;
					var flag=true;
					obj.find(controls).each(function(){
						var opt= obj.getruls($(this));						
						//验证不通过
						 flag= obj.valid($(this),opt);
						 //
						 if(!flag){
							 form.createvalid($(this),opt,true);
							//$(this).trigger('focus');	
						 }
						 return flag;//为false 时 each中断
					});
					return flag;
				},
				//指定显示错误
				showerror:function(id,index,flag,msg){
					var error= $('#'+id);
					var erroritem=null;
					var errorli=null;
					if(!error[0]){
						//创建
						return;
					}
					erroritem=error.find('li:eq('+index.toString()+')');					
					if(!erroritem[0]){
						//没有那项
						return;
					}
				 
					//分组
					var group= erroritem.attr('chk-group')||''; 
					erroritem.removeClass('error');
					if(!flag){ 
						erroritem.addClass('error');
					}else{
						//验证通过
						if(group!=''){
							//清除分组的 
							erroritem.siblings('[chk-group='+group+']').removeClass('error');
						}
					}
					if(undefined!=msg&&null!=msg&&''!=msg){	
						//修改
						erroritem.html(  '<i class="icon-checked"></i>'+msg);
					}
				},
				//清除验证成功的项
				clearsuccess:function(id){					
					var error= $('#'+id);				
					if(error.find('li.active')[0]){
						//当有验证未通过
						return;
					}else{
						//当验证全通过
						error.remove();
					}
				}
			});
			
			//以下事件使用 on 绑定，支持表单内异步添加输入框
			//获得焦点时
			form.on('focus',controls,function(){
				var input=$(this);   //自定义的验证				
				var opt=  form.getruls(input);
				
				if(opt.hasOwnProperty('isfocus')&& opt.isfocus==false){
					return;
				}
				form.createvalid(input,opt,true);
			}); 
			//输入时
			form.on('keyup keypress',controls,function(){
				var input=$(this);   		//自定义的验证
				var opt= form.getruls(input);	//当前规则			 
				
				//输入限定
				if(!form.extrememax(input,opt.rules)){
					return false;
				}
				//验证
				form.valid(input,opt);				
			}); 
			
			//离开时,验证全对才消除
			form.on('blur',controls,function(){
				var input=$(this);   //自定义的验证 
				var id=form.geterrorname(input);
				form.clearsuccess( id);
			});
			
			//处理事件冒泡冲突
			$(document).bind('click',function(e){
				 var target=$(e.target);
				 var errorid="";
				//点击tips本身
				if(target.parents('.J_form_tips')[0]){
					//关闭非自已的提示 
					$('.J_form_tips').not('#'+target.parents('.J_form_tips').prop('id') ).remove();
				}
				//点击tips关联的控件
				else if(target.is(controls)){
					errorid=  form.geterrorname( target );
					$('.J_form_tips').not('#'+ errorid ).remove();
				}
				//点击其它区域
				else{
					//非功能性的提交按钮
					//.J_form_submit 这个是非form的提交按钮
					//.J_button_submit  这个是提供form里面非submit按钮提交			
					//:submit   这个是兼容submit按钮提交
					if(!target.is('.J_form_submit,.J_button_submit,:submit')){
						$('.J_form_tips').remove();	
					}
				}
			});
			 
			//提交事件
			if(form.is('form')){
				//支持表单提交
				form.unbind('submit').submit(function(e){ 				
					//批量验证
					var flag=true;
					if(form.validates()){
						if(typeof settings.submit=='function'){						
							var ret= settings.submit(form);
							if(false===ret){
								//阻止窗口提交
								flag=false;
							}
						}
					}else{
						//验证失败
						flag=false;
					}
					return flag;
				});
			}else{
			//支持非 form容器验证
			   form.find('.J_form_submit').unbind('click').click(function(){				   
				   //批量验证
					var flag=true;
					if(form.validates()){
						if(typeof settings.submit=='function'){						
							var ret= settings.submit(form);
							if(false===ret){
								//阻止窗口提交
								flag=false;
							}
						}
					}else{
						//验证失败
						flag=false;
					}
					return flag;
			   });
			} 
			return form;
};
$.fn.validator=function(options){	
	return new Validator($(this),options );
};
})(jQuery);